#!/bin/sh /etc/rc.common
# Copyright (C) 2007-2012 OpenWrt.org

START=90

USE_PROCD=1

PDNSD_BIN="/var/sbin/dnscache"
DNSMASQ_RESTART=N
DNS_SERVER="114.114.114.114,114.114.115.115"

pdnsd_genconfig() {
	DNS_SERVER=$(uci get sfe.config.dns_server 2>/dev/null)

	[ -d /var/etc ] || mkdir -p /var/etc

	if [ ! -f /var/dnscache/pdnsd.cache ]; then
		mkdir -p /var/dnscache
		echo -ne "pd13\000\000\000\000" >/var/dnscache/pdnsd.cache
		chown -R nobody.nogroup /var/dnscache
	fi

	cat <<-EOF >/var/etc/dnscache.conf
		global {
			perm_cache=1024;        # dns缓存大小，单位KB，建议不要写的太大
			cache_dir="/var/dnscache";     # 缓存文件的位置
			pid_file="/var/run/dnscache.pid";
			run_as="nobody";
			server_ip = 0.0.0.0;        # pdnsd监听的网卡，0.0.0.0是全部网卡
			server_port=5333;           # pdnsd监听的端口，不要和别的服务冲突即可
			status_ctl = on;
			paranoid=on;                  # 二次请求模式，如果请求主DNS服务器返回的是垃圾地址，就向备用服务器请求
			query_method=udp_only;
			neg_domain_pol = off;
			par_queries = 400;          # 最多同时请求数
			min_ttl = 1h;               # DNS结果最短缓存时间
			max_ttl = 1w;               # DNS结果最长缓存时间
			timeout = 10;               # DNS请求超时时间，单位秒
		}

		server {
			label = "routine";
			ip = $DNS_SERVER;     # 这里为主要上级 dns 的 ip 地址，建议填写一个当地最快的DNS地址
			timeout = 5;              # DNS请求超时时间
			reject = 74.125.127.102,  # 以下是脏IP，也就是DNS污染一般会返回的结果，如果收到如下DNS结果会触发二次请求（TCP协议一般不会碰到脏IP）
				74.125.155.102,
				74.125.39.102,
				74.125.39.113,
				209.85.229.138,
				128.121.126.139,
				159.106.121.75,
				169.132.13.103,
				192.67.198.6,
				202.106.1.2,
				202.181.7.85,
				203.161.230.171,
				203.98.7.65,
				207.12.88.98,
				208.56.31.43,
				209.145.54.50,
				209.220.30.174,
				209.36.73.33,
				211.94.66.147,
				213.169.251.35,
				216.221.188.182,
				216.234.179.13,
				243.185.187.39,
				37.61.54.158,
				4.36.66.178,
				46.82.174.68,
				59.24.3.173,
				64.33.88.161,
				64.33.99.47,
				64.66.163.251,
				65.104.202.252,
				65.160.219.113,
				66.45.252.237,
				69.55.52.253,
				72.14.205.104,
				72.14.205.99,
				78.16.49.15,
				8.7.198.45,
				93.46.8.89,
				37.61.54.158,
				243.185.187.39,
				190.93.247.4,
				190.93.246.4,
				190.93.245.4,
				190.93.244.4,
				65.49.2.178,
				189.163.17.5,
				23.89.5.60,
				49.2.123.56,
				54.76.135.1,
				77.4.7.92,
				118.5.49.6,
				159.24.3.173,
				188.5.4.96,
				197.4.4.12,
				220.250.64.24,
				243.185.187.30,
				249.129.46.48,
				253.157.14.165;
			reject_policy = fail;
		}

		server {
			label = "special";                  # 这个随便写
			ip = 208.67.222.222,208.67.220.220; # 这里为备用DNS服务器的 ip 地址
			port = 5353;                        # 推荐使用53以外的端口（DNS服务器必须支持）
			proxy_only = on;
			timeout = 5;
		}

		source {
			owner=localhost;
		// serve_aliases=on;
			file="/etc/hosts";
		}

		rr {
			name=localhost;
			reverse=on;
			a=127.0.0.1;
			owner=localhost;
			soa=localhost,root.localhost,42,86400,900,86400,86400;
		}
	EOF

	[ -d /var/sbin ] || mkdir -p /var/sbin
	[ -f /var/sbin/dnscache ] || ln -s /usr/sbin/pdnsd /var/sbin/dnscache
}

change_dns() {
	uci delete dhcp.@dnsmasq[0].server >/dev/null 2>&1
	uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#5333
	uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto
	uci set dhcp.@dnsmasq[0].noresolv=0
	uci commit dhcp
}

revert_dns() {
	uci del_list dhcp.@dnsmasq[0].server=127.0.0.1#5333 >/dev/null 2>&1
	uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto
	uci set dhcp.@dnsmasq[0].noresolv=0
	uci commit dhcp
}

start_service() {
	enable=$(uci get sfe.config.enabled 2>/dev/null)
	wifi=$(uci get sfe.config.wifi)
	ipv6=$(uci get sfe.config.ipv6)
	dns=$(uci get sfe.config.dns 2>/dev/null)
	bbr=$(uci get sfe.config.bbr 2>/dev/null)

	if [ $enable -eq 1 ]; then
		! (lsmod | grep fast_classifier >/dev/null) && (modprobe fast_classifier)
		if [ $wifi -eq 1 ]; then
			echo 1 >/sys/fast_classifier/skip_to_bridge_ingress
		else
			echo 0 >/sys/fast_classifier/skip_to_bridge_ingress
		fi
		if [ $ipv6 -eq 1 ]; then
			sfe_ipv6=$(cat /sys/sfe_ipv6/debug_dev)
			[ ! -f /dev/sfe_ipv6 ] && mknod /dev/sfe_ipv6 c $sfe_ipv6 0
		else
			rm -f /dev/sfe_ipv6
		fi
	else
		rmmod fast_classifier >/dev/null 2>&1
	fi

	if [ $dns -eq 1 ]; then
		pdnsd_genconfig
		procd_open_instance
		procd_set_param command "$PDNSD_BIN" -c /var/etc/dnscache.conf
		procd_set_param respawn
		procd_set_param stderr 1
		procd_close_instance
		change_dns
	else
		revert_dns
	fi

	if [ $bbr -eq 1 ]; then
		sysctl -w net.ipv4.tcp_congestion_control=bbr
	else
		sysctl -w net.ipv4.tcp_congestion_control=cubic
	fi
	if [ "$DNSMASQ_RESTART" = N ]; then
		/etc/init.d/dnsmasq restart
	fi
}

stop_service() {
	enable=$(uci get sfe.config.enabled 2>/dev/null)
	[ $enable -ne 1 ] && rmmod fast_classifier >/dev/null 2>&1
	revert_dns
	if [ "$DNSMASQ_RESTART" = N ]; then
		/etc/init.d/dnsmasq restart
	fi
}

restart() {
	DNSMASQ_RESTART=Y
	stop
	start
	/etc/init.d/dnsmasq restart && echo "DNSMASQ restart"
}
